package com.ys.erp.stage_pet_service.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ys.erp.entity.data.bean.Cat;
import com.ys.erp.entity.data.bean.CatPhotoHistory;
import com.ys.erp.entity.service.ICatPhotoHistoryService;
import com.ys.erp.entity.service.ICatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang3.ObjectUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Log4j
public class RegularlyCheckPetPictures {

    private final ICatPhotoHistoryService iCatPhotoHistoryService;
    private final ICatService iCatService;
    private final RestTemplate restTemplate;
    private final RedissonClient redisson;

    private static final String OCR_URL = "https://mall.yscats.com/ocr/predict_batch";
    private static final String LOCK_KEY = "lock:pet:check_pictures";

    /**
     * 每五分钟执行一次，检查五分钟内上传的图片
     */
    @Scheduled(cron = "0 */5 * * * ?")
    public void petTask() {
        RLock lock = redisson.getLock(LOCK_KEY);
        boolean locked = lock.tryLock();
        if (!locked) {
            log.info("定时任务正在执行中");
            return;
        }
        try {
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime fiveMinutesAgo = now.minusMinutes(5);
            QueryWrapper<CatPhotoHistory> qw = new QueryWrapper<>();
            qw.lambda().ge(CatPhotoHistory::getUploadTime, fiveMinutesAgo)
                    .le(CatPhotoHistory::getUploadTime, now);
            List<CatPhotoHistory> photoList = iCatPhotoHistoryService.list(qw);
            if (ObjectUtils.isEmpty(photoList)) {
                log.info("五分钟内无新上传图片");
                return;
            }
            // 所有图片url
            Set<String> catCodeSet = new HashSet<>();
            for (CatPhotoHistory photo : photoList) {
                catCodeSet.add(photo.getCatCode());
            }
            if (catCodeSet.isEmpty()) {
                return;
            }
            // cat
            QueryWrapper<Cat> catQw = new QueryWrapper<>();
            catQw.lambda().in(Cat::getCatCode, catCodeSet);
            List<Cat> catList = iCatService.list(catQw);
            // 图片url和catCode
            List<String> imageUrls = new ArrayList<>();
            Map<String, String> catCodeMap = new HashMap<>(); // 图片url -> catCode
            for (Cat cat : catList) {
                if (ObjectUtils.isNotEmpty(cat.getPhotos())) {
                    String[] urls = cat.getPhotos().split(",");
                    for (String url : urls) {
                        imageUrls.add(url);
                        catCodeMap.put(url, cat.getCatCode());
                    }
                }
            }

            if (imageUrls.isEmpty()) {
                return;
            }
            // 调用OCR接口
            Map<String, Object> param = new HashMap<>();
            param.put("image_urls", imageUrls);
            Map ocrResult = restTemplate.postForObject(OCR_URL, param, Map.class);
            if (ocrResult == null || !ocrResult.containsKey("data")) {
                log.warn("OCR接口无返回或无data字段");
                return;
            }
            Map<String, String> resultMap = (Map<String, String>) ocrResult.get("data"); // url -> label
            Set<String> notCatDogUrls = resultMap.entrySet().stream()
                    .filter(e -> !"cat".equalsIgnoreCase(e.getValue()) && !"dog".equalsIgnoreCase(e.getValue()))
                    .map(Map.Entry::getKey)
                    .collect(Collectors.toSet());
            if (notCatDogUrls.isEmpty()) {
                log.info("全部图片为猫或狗，无需下架");
                return;
            }
            // 下架对应猫
            Set<String> catCodesToOff = notCatDogUrls.stream()
                    .map(catCodeMap::get)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            if (catCodesToOff.isEmpty()) {
                log.info("无需下架猫");
                return;
            }
            for (String catCode : catCodesToOff) {
                // 下架：catStatus=0在售->3下架，isShow=1->0
                Cat cat = new Cat();
                cat.setCatCode(catCode);
                cat.setIsShow(0);
                iCatService.update(cat, new QueryWrapper<Cat>().lambda().eq(Cat::getCatCode, catCode));
                log.info("已下架猫: " + catCode);
            }
        } catch (Exception e) {
            log.error("定时检查宠物图片异常", e);
        } finally {
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
    }
}
